package com.liujiayu.view.cirque;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import com.liujiayu.view.R;
import com.liujiayu.view.utils.DensityUtils;

/**
 * Created by liujiayu on 2017/8/28.
 */

public class CirqueView2 extends View {

    private Paint cirqueBackground;
    /**
     * 温度前景画笔
     */
    private Paint cirque;
    /**
     * 时间前景画笔
     */
    private Paint timecirque;
    private int radius;
    private Paint linePaint;
    private Paint timeLinePaint;
    private Paint textPaint;
    private Paint timeTextPaint;
    private float mCurrentAngle = 0;
    private int defaultValue;
    private RectF oval;
    private OnTurnFinishListener turnFinishListener;

    /**
     * 温度最小值
     */
    private int minTemp;
    /**
     * 温度最大值 250℃
     */
    private int maxTemp;
    // 最小功率
    private int minPower;
    // 最大功率 2500w
    private int maxPower;
    private int timeMinTxt;
    private int timeMaxTxt;

    /**
     * 当前是否显示温度
     */
    private boolean isTemp = true ;


    private Matrix mMatrix;
    /**
     * 设备是否连接
     */
    private boolean isDeviceConnected = false;

    int[] tempColors = {
            Color.parseColor("#FF9308"),
            Color.parseColor("#FF9308"),
            Color.parseColor("#FF9308"),
            Color.parseColor("#FF9308"),
            Color.parseColor("#FF9308"),
            Color.parseColor("#FE4F14"),
            Color.parseColor("#FE4F14"),
            Color.parseColor("#FE4F14"),
            Color.parseColor("#FE4F14"),
            Color.parseColor("#FE4F14")
    };
    int[] tempGradientColors = {
            Color.parseColor("#FF9308"),
            Color.parseColor("#FE4F14")
    };


    int[] timeColors = {
            Color.parseColor("#24D9D3"),
            Color.parseColor("#24D9D3"),
            Color.parseColor("#24D9D3"),
            Color.parseColor("#24D9D3"),
            Color.parseColor("#24D9D3"),
            Color.parseColor("#2E85F0"),
            Color.parseColor("#2E85F0"),
            Color.parseColor("#2E85F0"),
            Color.parseColor("#2E85F0"),
            Color.parseColor("#2E85F0")
    };
    float[] floats = {
            0.54f,
            0.96f
    };

    int[] timeGradientColors = {
            Color.parseColor("#2E85F0"),
            Color.parseColor("#24D9D3")
    };

    private SweepGradient mSweepGradient;

    private SweepGradient timeGradient ;

    private float mTimeCurrentAngle;

    private Context context;

    private String text;
    private String timeText;

    private String tempText , timeShowText ;

    /*温度文字画笔*/
    private Paint tempTxtPaint ;
    /*时间文字画笔*/
    private Paint timeTxtPaint ;
    /*文字矩形*/
    private Rect txtRect ;
    private float temperature;
    private float time;

    private Paint dividerLine ;

    public CirqueView2(Context context) {
        this(context, null);
    }

    public CirqueView2(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CirqueView2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initPaint();
        TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.cook_cirqueview, defStyleAttr, 0);
        minTemp = ta.getInteger(R.styleable.cook_cirqueview_cook_temperature_min, 0);
        minPower = ta.getInteger(R.styleable.cook_cirqueview_cook_power_min, 0);
        maxPower = ta.getInteger(R.styleable.cook_cirqueview_cook_power_max, 2200);
        maxTemp = ta.getInteger(R.styleable.cook_cirqueview_cook_temperature_max, 250);
        timeMinTxt = ta.getInteger(R.styleable.cook_cirqueview_cook_time_left, 0);
        timeMaxTxt = ta.getInteger(R.styleable.cook_cirqueview_cook_time_right, 120);
        ta.recycle();
    }

    private void initPaint() {
        defaultValue = DensityUtils.dip2px(context, 1.0f);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        cirqueBackground = new Paint();
        cirqueBackground.setStrokeWidth(DensityUtils.dip2px(context, 16.0f));
        cirqueBackground.setStrokeCap(Paint.Cap.ROUND);//充满
        cirqueBackground.setColor(Color.parseColor("#F0F0F0"));
//        cirqueBackground.setAlpha(50);
        cirqueBackground.setStyle(Paint.Style.STROKE);//设置空心
        cirqueBackground.setAntiAlias(true);//设置空心

        //温度前景画笔
        cirque = new Paint();
        cirque.setStrokeWidth(DensityUtils.dip2px(context, 16.0f));
        cirque.setStrokeCap(Paint.Cap.ROUND);
        cirque.setStyle(Paint.Style.STROKE);//设置空心
        cirque.setAntiAlias(true);//设置空心

        //时间前景画笔
        timecirque = new Paint();
        timecirque.setStrokeWidth(DensityUtils.dip2px(context, 16.0f));
        timecirque.setStrokeCap(Paint.Cap.ROUND);
        timecirque.setStyle(Paint.Style.STROKE);//设置空心
        timecirque.setAntiAlias(true);//设置空心
        mMatrix = new Matrix();


        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setStrokeWidth(DensityUtils.dip2px(context, 2.0f));

        timeLinePaint = new Paint();
        timeLinePaint.setAntiAlias(true);
        timeLinePaint.setColor(Color.parseColor("#747F9D"));
        timeLinePaint.setStrokeWidth(DensityUtils.dip2px(context, 2.0f));

        textPaint = new Paint();  // 温度画笔
//        textPaint.setColor(getResources().getColor(R.color.cook_green));
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(DensityUtils.dip2px(context, 24.0f));

        timeTextPaint = new Paint(); // 时间画笔
//        timeTextPaint.setColor(Color.parseColor("#747F9D"));
        timeTextPaint.setAntiAlias(true);
        timeTextPaint.setTextSize(DensityUtils.dip2px(context, 24.0f));

        tempTxtPaint = new Paint();
        tempTxtPaint.setAntiAlias(true);
        tempTxtPaint.setTextSize(DensityUtils.dip2px(context, 15.0f));
        tempTxtPaint.setTextAlign(Paint.Align.CENTER);
        txtRect = new Rect();
        /*时间*/
        timeTxtPaint = new Paint();
        timeTxtPaint.setAntiAlias(true);
        timeTxtPaint.setTextSize(DensityUtils.dip2px(context, 15.0f));
        timeTxtPaint.setTextAlign(Paint.Align.CENTER);
        timeShowText = "计时" ;
        timeTxtPaint.getTextBounds(timeShowText, 0, timeShowText.length(), txtRect );

        oval = new RectF();

        dividerLine = new Paint();
        dividerLine.setColor(Color.parseColor("#F0F0F0"));
        dividerLine.setAntiAlias(true);
        dividerLine.setStrokeWidth(DensityUtils.dip2px(context,1.0f));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        radius = (getWidth() / 2) - DensityUtils.dip2px(context, 21.0f);
        // 设置椭圆角度
        oval.set(getWidth() / 2.0f - radius - defaultValue,
                getHeight() / 2.0f - radius - defaultValue,
                getWidth() / 2.0f + radius + defaultValue,
                getHeight() / 2.0f + radius + defaultValue);
        // 为温度圆弧设置渐变色值
        mSweepGradient = new SweepGradient(getWidth() / 2, getHeight() / 2, tempGradientColors, floats);
        cirque.setShader(mSweepGradient);
        timeGradient = new SweepGradient(getWidth() / 2 , getHeight() / 2 , timeGradientColors, floats);
        mMatrix.setRotate(-165,getWidth() / 2 , getHeight() / 2);
        timeGradient.setLocalMatrix(mMatrix);
        timecirque.setShader(timeGradient);
    }

    private int measure(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            //这样，当时用wrap_content时，View就获得一个默认值200px，而不是填充整个父布局。
            result = DensityUtils.dip2px(context, 200f);
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //弧形底部默认背景
        canvas.drawArc(oval, 195, 150, false, cirqueBackground);//温度底部小弧形
        canvas.drawArc(oval, 15, 150, false, cirqueBackground);//小弧形
        //绘制前景温度弧形
        if (mCurrentAngle != 0) {
            canvas.drawArc(oval, 195, mCurrentAngle, false, cirque);//小弧形
        }
        //绘制前景时间弧形
        if (mTimeCurrentAngle != 0) {
            canvas.drawArc(oval, 165, -mTimeCurrentAngle, false, timecirque);//小弧形
        }
        //文字以及图标绘制
        int timeV = timeMaxTxt - timeMinTxt;
        if (isTemp) {
            // 温度
            int v = maxTemp - minTemp;
            text = Math.round(mCurrentAngle / (150f / v)) + minTemp + "℃";
            tempText = "温度";
        } else {
            // 功率
            int v = maxPower - minPower;
            int tempOrPower = Math.round(mCurrentAngle / (150f / v)) + minPower ;
            text =  tempOrPower + "w";
            if (tempOrPower < 550) {
                tempText = "微火";
            } else if (tempOrPower > 550 && tempOrPower < 1100) {
                tempText = "小火";
            } else if (tempOrPower > 1100 && tempOrPower < 1650) {
                tempText = "中火";
            } else {
                tempText = "大火";
            }
        }
        tempTxtPaint.getTextBounds(tempText, 0, tempText.length(), txtRect );
        // 时间
        timeText = Math.round(mTimeCurrentAngle / (150f / timeV)) + timeMinTxt + "min";
        // 设置温度文字画笔颜色（随滑动的颜色数组改变）
        textPaint.setColor(tempColors[(int) (mCurrentAngle / (15 + 0.5f))]);
        tempTxtPaint.setColor(tempColors[(int) (mCurrentAngle / (15 + 0.5f))]);
        timeTextPaint.setColor(timeColors[(int) (mTimeCurrentAngle / (15 + 0.5f))]);
        timeTxtPaint.setColor(timeColors[(int) (mTimeCurrentAngle / (15 + 0.5f))]);
        // 绘制显示的温度 / 火力文字
        canvas.drawText(tempText, getWidth() / 2.0f, getHeight() / 2.0f - DensityUtils.dip2px(context, 50.0f) - txtRect.height(), tempTxtPaint);
        // 绘制上方温度文字
        canvas.drawText(text, getWidth() / 2.0f - textPaint.measureText(text) / 2, getHeight() / 2.0f - DensityUtils.dip2px(context, 30.0f), textPaint);
        /*绘制中间直线*/
        canvas.drawLine(DensityUtils.dip2px(context, 50.0f), getHeight() /2.0f, getWidth() - DensityUtils.dip2px(context, 50.0f), getHeight() /2.0f ,dividerLine);
        // 绘制时间文字
        canvas.drawText(timeText, getWidth() / 2.0f - timeTextPaint.measureText(timeText) / 2, getHeight() / 2 + DensityUtils.dip2px(context, 40f), timeTextPaint);
        /*绘制时间文字二字*/
        canvas.drawText(timeShowText, getWidth() / 2.0f, getHeight() / 2.0f + DensityUtils.dip2px(context, 50f) + txtRect.height(), timeTxtPaint);

        //刻度绘制竖线
        linePaint.setColor(tempColors[(int) (mCurrentAngle / (15 + 0.5f))]);
        timeLinePaint.setColor(timeColors[(int) (mTimeCurrentAngle / (15 + 0.5f))]);
        canvas.rotate(mCurrentAngle + 15f, getWidth() / 2, getHeight() / 2);
        canvas.drawCircle(getWidth() / 2.0f - radius - defaultValue - DensityUtils.dip2px(context, 1f),
                getHeight() / 2,
                DensityUtils.dip2px(context, 12.0f),
                linePaint);
        canvas.rotate(-mTimeCurrentAngle - 30f - mCurrentAngle, getWidth() / 2, getHeight() / 2);
        canvas.drawCircle(getWidth() / 2.0f - radius - defaultValue - DensityUtils.dip2px(context, 1f),
                getHeight() / 2,
                DensityUtils.dip2px(context, 12.0f),
                timeLinePaint);
    }

    /**
     * @param isTemp 设置是显示温度还是功率
     */
    public void setTempVal(boolean isTemp) {
        this.isTemp = isTemp;
        invalidate();
    }

    public boolean isTemp() {
        return isTemp;
    }

    /**
     * 设置初始值
     *
     * @param temperature 温度/功率
     * @param time        时间
     */
    public void setDefault(int temperature, int time) {
        setCountTime(time);
        setTemperature(temperature);
    }

    /**
     * 设置温度/功率
     *
     * @param value 温度/功率
     */
    public void setTemperature(int value) {
        if (isTemp) {
            if (value < minTemp || value > maxTemp) {
                throw new RuntimeException("Temperature out of range");
            }
            this.temperature = (float) (value - minTemp) / (maxTemp - minTemp) * 150f;
        } else {
            if (value < minPower || value > maxPower) {
                throw new RuntimeException("Temperature out of range");
            }
            this.temperature = (float) (value - minPower) / (maxPower - minPower) * 150f;
        }
        startTempAnim();
    }


    /**
     * 设置倒计时
     *
     * @param value 时间
     */
    public void setCountTime(int value) {
        if (value < timeMinTxt || value > timeMaxTxt) {
            throw new RuntimeException("Time out of range");
        }
        this.time = (float) (value - timeMinTxt) / (timeMaxTxt - timeMinTxt) * 150f;
        startTimeAnim();
    }

    /**
     * 执行时间动画效果
     */
    private void startTimeAnim() {
        ValueAnimator mTimeAngleAnim = ValueAnimator.ofFloat(0, time);
        mTimeAngleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
        mTimeAngleAnim.setDuration(1500);
        mTimeAngleAnim.addUpdateListener(valueAnimator -> {
            mTimeCurrentAngle = (float) valueAnimator.getAnimatedValue();
            postInvalidate();
        });
        mTimeAngleAnim.start();
    }

    /**
     * 执行温度动画
     */
    private void startTempAnim(){
        ValueAnimator mAngleAnim = ValueAnimator.ofFloat(0, temperature);
        mAngleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
        mAngleAnim.setDuration(1500);
        mAngleAnim.addUpdateListener(valueAnimator -> {
            mCurrentAngle = (float) valueAnimator.getAnimatedValue();
            postInvalidate();
        });
        mAngleAnim.start();
    }

    /**
     * 区分是时间区域滑动还是温度区域滑动
     * true 温度区域（上部分）
     * false 时间区域
     */
    boolean tag = false;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 检查设备是否已连接，暂时通过 BleCookUtils 处理判断。
//        if (!BleCookUtils.cookerIsConnected()) {
//            ToastKit.show("请先连接电磁炉设备！");
//            return true;
//        }
        /*获取点击位置的坐标*/
        float Action_x = event.getX();
        float Action_y = event.getY();
        /*根据坐标转换成对应的角度*/
        float get_x0 = Action_x - getWidth() / 2.0f;
        float get_y0 = Action_y - getHeight() / 2.0f;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (Action_y < getHeight() / 2.0f) { //温度
                    tag = true;
                } else {//时间
                    tag = false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (tag) { //温度
                    /*02：左上角区域*/
                    if (get_x0 <= 0 & get_y0 <= 0) {
                        float tan_x = get_x0 * (-1);
                        float tan_y = get_y0 * (-1);
                        double atan = Math.atan(tan_y / tan_x);
                        mCurrentAngle = (int) Math.toDegrees(atan);
                    }

                    /*03：右上角区域*/
                    if (get_x0 >= 0 & get_y0 <= 0) {
                        float tan_x = get_x0;
                        float tan_y = get_y0 * (-1);
                        double atan = Math.atan(tan_x / tan_y);
                        mCurrentAngle = (int) Math.toDegrees(atan) + 90f;
                    }
                    if (Math.abs(mCurrentAngle) <= 1 || (get_x0 <= 0 & get_y0 >= 0))
                        mCurrentAngle = 0;
                    if (Math.abs(mCurrentAngle) >= 149 || (get_x0 >= 0 & get_y0 >= 0))
                        mCurrentAngle = 150;
                } else if (!tag) { //时间
                    /*01：左下角区域*/
                    if (get_x0 <= 0 & get_y0 >= 0) {
                        float tan_x = get_x0 * (-1);
                        float tan_y = get_y0;
                        double atan = Math.atan(tan_x / tan_y);
                        mTimeCurrentAngle = -(int) Math.toDegrees(atan) + 90f;
                    }

                    /*04：右下角区域*/
                    if (get_x0 >= 0 & get_y0 >= 0) {
                        float tan_x = get_x0;
                        float tan_y = get_y0;
                        double atan = Math.atan(tan_y / tan_x);
                        mTimeCurrentAngle = -(int) Math.toDegrees(atan) + 180f;
                    }

                    if (Math.abs(mTimeCurrentAngle) <= 1 || (get_x0 <= 0 & get_y0 <= 0))
                        mTimeCurrentAngle = 0;
                    if (Math.abs(mTimeCurrentAngle) >= 149 || (get_x0 >= 0 & get_y0 <= 0))
                        mTimeCurrentAngle = 150;
                }
                break;
            case MotionEvent.ACTION_UP:
                //文字以及图标绘制
                int timeV = timeMaxTxt - timeMinTxt;
                int tempOrPower;
                if (isTemp) {
                    // 温度
                    int v = maxTemp - minTemp;
                    tempOrPower = Math.round(mCurrentAngle / (150f / v)) + minTemp;
                } else {
                    // 功率
                    int v = maxPower - minPower;
                    tempOrPower = Math.round(mCurrentAngle / (150f / v)) + minPower;
                }
                // 时间
                timeV = Math.round(mTimeCurrentAngle / (150f / timeV)) + timeMinTxt;
                if (turnFinishListener != null) {  //监听
                    if (tag) { // temperature
                        turnFinishListener.onTemperatureChanged(isTemp, tempOrPower);
                    } else { // time changed
                        turnFinishListener.onTimeChanged(timeV);
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
        }

        /*得到点的角度后进行重绘*/
        invalidate();
        return true;
    }

    /**
     * 设置设备
     * @param isDeviceConnected 已连接设备
     */
    public void setIsDeviceConnected(boolean isDeviceConnected) {
        this.isDeviceConnected = isDeviceConnected;
    }

    /**
     * @return 设备是否已连接
     */
    public boolean isDeviceConnected() {
        return this.isDeviceConnected ;
    }

    private Bitmap conversionBitmap(Bitmap bitmap, int newWidth, int newHeight) {
        Bitmap bitMap = bitmap;
        int width = bitMap.getWidth();
        int height = bitMap.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        return Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix, true);
    }

    /**
     * 数值设置完成后的回调
     */
    public interface OnTurnFinishListener {
        /**
         * 上部区域值改变
         * @param isTemp    当前是温度模式还是功率模式
         * @param tempeOrPower  数值
         */
        void onTemperatureChanged(boolean isTemp, int tempeOrPower);

        /**
         * 下半区域值改变
         * @param time  时间
         */
        void onTimeChanged(int time);
    }

    /**
     * @return 获取旋钮监听事件
     */
    public OnTurnFinishListener getTurnFinishListener() {
        return turnFinishListener;
    }

    /**
     * @param turnFinishListener 设置旋钮监听事件
     */
    public void setTurnFinishListener(OnTurnFinishListener turnFinishListener) {
        this.turnFinishListener = turnFinishListener;
    }

    /**
     * 设置温度
     *
     * @param temperatureMin 最小温度
     * @param temperatureMax 最大温度
     */
    public void setTemperaturemin(int temperatureMin, int temperatureMax) {
        if (temperatureMin >= temperatureMax) {
            throw new RuntimeException("Temperature range anomaly");
        }
        this.minTemp = temperatureMin;
        this.maxTemp = temperatureMax;
    }

    /**
     * 设置功率
     *
     * @param powerMin 最小温度
     * @param powerMax 最大温度
     */
    public void setPowerValue(int powerMin, int powerMax) {
        if (powerMin >= powerMax) {
            throw new RuntimeException("Power range anomaly");
        }
        this.minPower = powerMin;
        this.maxPower = powerMax;
    }

    /**
     * 设置时间
     *
     * @param timeMin 最小时间
     * @param timeMax 最大时间
     */
    public void setTimeValue(int timeMin, int timeMax) {
        if (timeMin < 0 || timeMin >= timeMax) {
            throw new RuntimeException("Time cannot be negative or Time domain anomaly");
        }
        this.timeMinTxt = timeMin;
        this.timeMaxTxt = timeMax;
    }

    public int getMinTemp() {
        return minTemp;
    }

    public int getMaxTemp() {
        return maxTemp;
    }

    public int getTimeMinTxt() {
        return timeMinTxt;
    }

    public int getTimeMaxTxt() {
        return timeMaxTxt;
    }

    public int getMinPower() {
        return minPower;
    }

    public void setMinPower(int minPower) {
        this.minPower = minPower;
    }

    public int getMaxPower() {
        return maxPower;
    }

    public void setMaxPower(int maxPower) {
        this.maxPower = maxPower;
    }


}
